package com.scujj.cs6.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scujj.cs6.common.BusinessException;
import com.scujj.cs6.common.ErrorCode;
import com.scujj.cs6.mapper.QuestionMapper;
import com.scujj.cs6.model.dto.question.QuestionCreateDTO;
import com.scujj.cs6.model.dto.question.QuestionUpdateDTO;
import com.scujj.cs6.model.entity.*;
import com.scujj.cs6.model.vo.FollowQuestionVo;
import com.scujj.cs6.model.vo.PageVo;
import com.scujj.cs6.model.vo.QuestionVo;
import com.scujj.cs6.service.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author FlanChan
 * @description 针对表【question】的数据库操作Service实现
 * @createDate 2025-03-25 21:21:24
 */
@Service
@AllArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
        implements QuestionService {

    private final QuestionTopicService questionTopicService;

    private final QuestionTagService questionTagService;

    private final TopicService topicService;

    private final TagService tagService;

    @Override
    public List<QuestionVo> getTop5Questions() {
        return this.baseMapper.selectTop5Q();
    }

    @Override
    public PageVo<QuestionVo> getQuestions(int page, int size, List<String> tags, String topic) {
        if (topic != null && !topic.isEmpty() && !topic.isBlank() && topicService.count(new LambdaQueryWrapper<>(Topic.class).eq(Topic::getName, topic)) == 0) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "话题不存在!");
        }
        if (tags != null && !tags.isEmpty() && tagService.count(new LambdaQueryWrapper<>(Tag.class).in(Tag::getName, tags)) != tags.size()) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "存在非法标签!");
        }
        // 计算分页参数
        int offset = (page - 1) * size;

        // 查询数据
        List<QuestionVo> questions = this.baseMapper.queryQuestions(tags, topic, offset, size);

        // 查询总数
        int total = this.baseMapper.countQuestions(tags, topic);
        int totalPage = (total + size - 1) / size;
        // 封装分页对象
        return new PageVo<>(page, size, totalPage, total, questions);
    }

    @Override
    public PageVo<FollowQuestionVo> getFollowQuestions(int page, int size, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("user");

        // 计算分页偏移量
        int offset = (page - 1) * size;

        // 获取当前用户关注的用户的提问
        List<FollowQuestionVo> questions = this.baseMapper.selectMyFollowedQuestions(userId, offset, size);

        // 查询总数量
        int total = this.baseMapper.countFollowedQuestions(userId);

        // 计算总页数
        int totalPage = (total + size - 1) / size;

        // 返回分页对象
        return new PageVo<>(page, size, totalPage, total, questions);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createQuestion(QuestionCreateDTO questionDTO, HttpServletRequest request) {
        List<String> tags = questionDTO.getTags();
        if (tags == null || tags.isEmpty()) {
            throw new RuntimeException("标签不能为空!");
        }
        List<Tag> tagList = tagService.list(new LambdaQueryWrapper<>(Tag.class).in(Tag::getName, tags));
        if (tagList.size() != tags.size()) {
            throw new RuntimeException("发现存在非法的标签!");
        }

        String topic = questionDTO.getTopic();
        Topic top = topicService.getOne(new LambdaQueryWrapper<>(Topic.class).eq(Topic::getName, topic));
        if (top == null) {
            throw new RuntimeException("话题不存在!");
        }

        Question question = new Question(questionDTO);
        long id = IdWorker.getId();
        question.setId(id);
        question.setUserId((Long) request.getAttribute("user"));
        this.save(question);

        QuestionTopic questionTopic = new QuestionTopic();
        questionTopic.setQuestionId(question.getId());
        questionTopic.setTopicId(top.getId());
        questionTopicService.save(questionTopic);

        questionTagService.saveBatch(tagList.stream().map(tag -> {
            QuestionTag questionTag = new QuestionTag();
            questionTag.setQuestionId(id);
            questionTag.setTagId(tag.getId());
            return questionTag;
        }).toList());
    }

    @Override
    public void updateQuestion(Long id, QuestionUpdateDTO questionDTO, HttpServletRequest request) {
        Question question = new Question(questionDTO);
        question.setId(id);
        question.setUserId((Long) request.getAttribute("user"));
        this.updateById(question);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteQuestion(Long id) {
        if (this.getById(id) == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "问题不存在!");
        }
        this.baseMapper.deleteQuestionWithRelations(id);
    }

    @Override
    public PageVo<QuestionVo> getMyQuestions(int page , int size, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("user");

        // 计算分页偏移量
        int offset = (page - 1) * size;

        // 查询数据
        List<QuestionVo> questions = this.baseMapper.selectMyQuestions(userId, offset, size);

        // 查询总数（可优化，避免多次查询）
        int total = this.baseMapper.countMyQuestions(userId);
        int totalPages = (total + size - 1) / size;

        return new PageVo<>(page, size, totalPages, total, questions);
    }

    @Override
    public QuestionVo getQuestionById(Long id) {
        return this.baseMapper.selectQuestionById(id);
    }
}




